package com.second.app.future;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @Author GYZ
 * @Date 2024/2/1
 * <pre>
 *  1.使用completionService解决future的缺点。
 *  2.使用poll(long timeout,TimeUnit unit):等待指定的timeout时间，在timeout时间内获取值立即向下继续执行
 *    如果超时，也立即向下执行。
 * </pre>
 */
public class CompletionServiceRun {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        CustomCallable callable1 = new CustomCallable("username1", 5000);
        CustomCallable callable2 = new CustomCallable("username2", 4000);
        CustomCallable callable3 = new CustomCallable("username3", 3000);
        CustomCallable callable4 = new CustomCallable("username4", 2000);
        CustomCallable callable5 = new CustomCallable("username5", 1000);

        List<Callable> callables = new ArrayList<>();
        callables.add(callable1);
        callables.add(callable2);
        callables.add(callable3);
        callables.add(callable4);
        callables.add(callable5);

        ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
                10,
                5,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>());
        ExecutorCompletionService csRef = new ExecutorCompletionService(executor);

        for (int i=0;i<5;i++){
            csRef.submit(callables.get(i));
        }
//
//        for (int i=0;i<5;i++){
//            System.out.println("等待打印第"+(i+1)+"个返回值");
//            System.out.println(csRef.take().get());
//        }

        for (int i=0;i<6;i++){//循环次数，变为6次
            System.out.println("等待打印第"+(i+1)+"个返回值");
            System.out.println(csRef.take().get());
        }
    }
    //从打印的结果来看，使用completionService接口后，哪个任务先执行完，哪个任务的返回值就先打印
    //在completionService接口中如果当前没有任务执行完成，则csRef.take().get()方法还是具有阻塞性
}
class CustomCallable implements Callable<String>{

    private String username;

    private long sleepValue;

    public CustomCallable(String username, long sleepValue) {
        this.username = username;
        this.sleepValue = sleepValue;
    }

    @Override
    public String call() throws Exception {
        System.out.println(username);
        Thread.sleep(sleepValue);
        return "return "+username;
    }
}
class Custom1Callable implements Callable<String>{

    @Override
    public String call() throws Exception {
        Thread.sleep(5000);
        System.out.println("Custom1Callable "+System.currentTimeMillis());
        return "returnA";
    }
}
class Custom2Callable implements Callable<String>{

    @Override
    public String call() throws Exception {
        Thread.sleep(10000);
        System.out.println("Custom2Callable "+System.currentTimeMillis());
        return "returnA";
    }
}

class MainTest{
    public static void main(String[] args) throws InterruptedException {
        Custom1Callable custom1Callable = new Custom1Callable();
        Custom2Callable custom2Callable = new Custom2Callable();

        ExecutorService executor = Executors.newCachedThreadPool();
        ExecutorCompletionService executorCompletionService = new ExecutorCompletionService<>(executor);
        executorCompletionService.submit(custom1Callable);
        executorCompletionService.submit(custom2Callable);
//        for (int i = 0; i < 2; i++) {
//            System.out.println("zzzzzzzzzzzzzzzzz"+" "+executorCompletionService.poll());
//        }
        for (int i = 0; i < 2; i++) {
            System.out.println("zzzzzzzzzzzzzzzzz"+" "+executorCompletionService.poll(6,TimeUnit.SECONDS));
        }
        System.out.println("main end ");
    }
    //执行结果看：返回2个null值，因为任务没有执行完毕

}

